package com.lagou.boot;

import ch.qos.logback.core.net.SocketConnector;
import com.lagou.decoder.RpcDecoder;
import com.lagou.exception.ServerErrorHandler;
import com.lagou.handler.UserServiceHandler;
import com.lagou.model.RpcRequest;
import com.lagou.serializer.JSONSerializer;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringEncoder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

@Component
public class NettyServer {


    @Autowired
    private ApplicationContext applicationContext;

    //1.创建两个线程池对象
    private NioEventLoopGroup bossGroup = new NioEventLoopGroup();
    private NioEventLoopGroup workGroup = new NioEventLoopGroup();


    @PostConstruct
    public void startServer() throws InterruptedException {


        //2.创建服务端的启动引导对象
        ServerBootstrap serverBootstrap = new ServerBootstrap();

        //3.配置启动引导对象
        serverBootstrap.group(bossGroup, workGroup)
                       //设置通道为NIO
                       .channel(NioServerSocketChannel.class)
                       //创建监听channel
                       .childHandler(new ChannelInitializer<NioSocketChannel>() {
                           protected void initChannel(NioSocketChannel nioSocketChannel) {
                               //获取管道对象
                               ChannelPipeline pipeline = nioSocketChannel.pipeline();
                               //给管道对象pipeLine 设置编码
                               pipeline.addLast(new RpcDecoder(RpcRequest.class, new JSONSerializer()));
                               pipeline.addLast(new StringEncoder());
                               //把我们自顶一个ChannelHander添加到通道中
                               pipeline.addLast(new UserServiceHandler(applicationContext));
                               pipeline.addLast(new ServerErrorHandler());
                           }
                       });

        //4.绑定端口
        ChannelFuture future = serverBootstrap.bind(8999)
                                              .sync();
        if (future.isSuccess()) {
            System.out.println("》》》》》》》》netty启动成功");
        }
    }

    @PreDestroy
    public void destory() throws InterruptedException {
        bossGroup.shutdownGracefully()
                 .sync();
        workGroup.shutdownGracefully()
                 .sync();
        System.out.println("关闭Netty》》》》》》》");
    }

}
